import { getApi } from '@/requestConfig';
import { authorizeRenewOSS } from '@/services/api/api-aliyun';
import { getToken } from '@/utils/token';
import { PlusOutlined } from '@ant-design/icons';
import OSS from 'ali-oss';
import { GetProp, Image, message, Upload } from 'antd';
import { UploadFile } from 'antd/es/upload/interface';
import { UploadProps } from 'antd/lib';
import moment from 'moment';
import { useState } from 'react';
import { useModel } from 'umi';

interface UploadVideoProps {
  access: {
    isVideo: boolean;
  };
  url?: string;
  maxCount: number;
  value?: UploadFile[];
  placeholder: string;
  onChange?(value: UploadFile[]): void;
  onPreview(file: UploadFile | undefined): void;
}

const UploadVideo: React.FC<UploadVideoProps> = ({
  access,
  url,
  maxCount,
  value,
  placeholder,
  onChange,
  onPreview,
}) => {
  const { initialState, setInitialState } = useModel('@@initialState');

  const [preview, setPreviewState] = useState<UploadFile>();

  const customRequest = async (options: any) => {
    if (options.file !== undefined && options.file.name !== undefined) {
      const fileType = options.file.name.split('.').pop().toLocaleLowerCase(); //小写

      if (fileType === undefined || fileType === null || fileType === '') {
        message.error('文件名出错');
        options.onError('文件名出错', options.file);
        return;
      }

      if (
        access.isVideo &&
        (fileType === 'mp3' ||
          fileType === 'mp4' ||
          fileType === 'wav' ||
          fileType === 'flv' ||
          fileType === 'avi' ||
          fileType === 'mov' ||
          fileType === 'rm' ||
          fileType === 'webm' ||
          fileType === 'ts' ||
          fileType === 'mkv' ||
          fileType === 'mpeg' ||
          fileType === 'ogg' ||
          fileType === 'mpg' ||
          fileType === 'rmvb' ||
          fileType === 'wmv' ||
          fileType === '3gp' ||
          fileType === 'swf ')
      ) {
        const isLt5GB = options.file.size / 1024 / 1024 / 1024 < 5;
        if (!isLt5GB) {
          message.error('文件大小不超过 5 GB');
          options.onError('文件大小不超过 5 GB', options.file);
          return;
        }
      } else {
        message.error('不支持该格式文件');
        options.onError('不支持该格式文件', options.file);
        return;
      }

      const response = await authorizeRenewOSS();

      if (response.code === 0) {
        const headers = {
          'Content-Disposition': 'attachment;',
          'Content-Type': options.file.type,
        };

        const multipartUploadOptions = {
          callback: {
            url: getApi() + url,
            body: response.data.callbackBody,
            contentType: response.data.callbackContentType,
            satoken: getToken(),
          },
          progress: (p: number, cpt: any, res: any) => {
            options.onProgress({ percent: Math.round(p * 100).toFixed(2) }, options.file);
          },
          headers,
        };

        const OSSData = {
          accessKeyId: response.data.accessKeyId,
          accessKeySecret: response.data.accessKeySecret,
          stsToken: response.data.securityToken,
          region: response.data.callbackRegion,
          bucket: response.data.callbackBucket,
        };

        const client = new OSS({
          region: OSSData.region,
          accessKeyId: OSSData.accessKeyId,
          accessKeySecret: OSSData.accessKeySecret,
          stsToken: OSSData.stsToken,
          refreshSTSToken: async () => {
            const response = await authorizeRenewOSS();
            return {
              accessKeyId: response.data.accessKeyId,
              accessKeySecret: response.data.accessKeySecret,
              stsToken: response.data.securityToken,
            };
          },
          refreshSTSTokenInterval: 300000,
          bucket: OSSData.bucket,
        });

        client
          .multipartUpload(
            `${initialState?.currentUser?.organizationName}/assess/render/${moment().format(
              'YYYY-MM-DD',
            )}/${options.file.name}`,
            options.file,
            multipartUploadOptions,
          )
          .then((response: any) => {
            if (response.data.code === 0) {
              console.log('===========成功=============', response.data, options.file);

              options.onSuccess(response.data, options.file);
            } else {
              options.onError(response.data.msg, options.file);
            }
          })
          .catch((e: any) => {
            options.onError('发生错误', options.file);
          });
      }
    } else {
      message.error('文件出错啦');
      options.onError('文件出错啦', options.file);
      return;
    }
  };

  const handlePreview = async (file: UploadFile) => {
    // onLoading(true);

    console.log('======handlePreview=====', file);

    if (file?.status === 'done' && file.response && file.response?.data?.id) {
      if (!file.url && !file.preview) {
        file.preview = await getBase64(file.originFileObj as FileType);
      }

      setPreviewImage(file.url || (file.preview as string));
      setPreviewOpen(true);
    } else {
      message.warning('暂无预览数据');
    }
  };

  const handleChange: UploadProps['onChange'] = ({ fileList }) => {
    console.log('====handleChange==============', fileList);

    if (onChange) {
      onChange(fileList);
    }

    setFileList(fileList);
  };

  type FileType = Parameters<GetProp<UploadProps, 'beforeUpload'>>[0];

  const [previewOpen, setPreviewOpen] = useState(false);
  const [previewImage, setPreviewImage] = useState('');
  const [fileList, setFileList] = useState<UploadFile[]>([]);

  const getBase64 = (file: FileType): Promise<string> =>
    new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => resolve(reader.result as string);
      reader.onerror = (error) => reject(error);
    });

  return (
    <>
      <Upload
        listType="picture-card"
        multiple
        fileList={value}
        customRequest={customRequest}
        onPreview={handlePreview}
        onChange={handleChange}
        maxCount={maxCount}
      >
        {fileList.length == maxCount ? null : (
          <button style={{ border: 0, background: 'none' }} type="button">
            <PlusOutlined />
            <div style={{ marginTop: 8 }}>{placeholder}</div>
          </button>
        )}
      </Upload>
      {previewImage && (
        <Image
          wrapperStyle={{ display: 'none' }}
          preview={{
            visible: previewOpen,
            onVisibleChange: (visible) => setPreviewOpen(visible),
            afterOpenChange: (visible) => !visible && setPreviewImage(''),
          }}
          src={previewImage}
        />
      )}
    </>
  );
};

export default UploadVideo;
